package view.content;

import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Dimension;
import java.util.logging.Level;

import model.Preference;
import model.Settings;
import model.contents.Content;
import platform.Platform;
import uk.co.caprica.vlcj.binding.internal.libvlc_media_t;
import uk.co.caprica.vlcj.component.EmbeddedMediaPlayerComponent;
import uk.co.caprica.vlcj.player.MediaPlayer;
import uk.co.caprica.vlcj.player.MediaPlayerEventListener;
import uk.co.caprica.vlcj.player.MediaPlayerFactory;
import uk.co.caprica.vlcj.player.embedded.FullScreenStrategy;
import util.EmailSending;
import util.LoggingUtils;
import util.PlayerUtilities;

/**
 * An absolute minimum test player.
 */
public class VideoBox extends ContentBox implements MediaPlayerEventListener {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private static boolean supported = true; 
	private EmbeddedMediaPlayerComponent mediaPlayerComponent;
	private Object playLock;
	protected final String className = this.getClass().getName();
	
	public static boolean isSupported() {
		if(Platform.getPlatform()!=platform.Platform.LINUX && Platform.getPlatform()!=Platform.WINDOWS) {
			return false;
		}
		return supported;
	}
	
	public VideoBox(Content c, int width, int height) {
		super(c, width, height);
		//this.cleanup();
		this.init();
	}				

	private void init() {
		this.setSize(new Dimension(this.getWidth(), this.getHeight()));
		this.setLayout(new BorderLayout());
		this.setIgnoreRepaint(true);
		//this.setOpaque(true);
		this.setDoubleBuffered(true);
		
		this.playLock = new Object();
	}

	public void play() {
		final String classMethod = className + ".play()";
        LoggingUtils.logStart(classMethod);
        System.out.println("Playing video");
        
        this.content.getId();
        
		try {
			this.mediaPlayerComponent = new MyEmbeddedMediaPlayerComponent();
			this.add(mediaPlayerComponent);
			this.revalidate();
			this.repaint();
			//this.setVisible(true);
			MediaPlayer mediaPlayer = mediaPlayerComponent.getMediaPlayer();
			//mediaPlayer.setTitle(0);
			mediaPlayer.addMediaPlayerEventListener(this);
			//mediaPlayer.enableMarquee(true);
			/*
			String[] options = {
                    ":sharpen-sigma=2.0", 
                    ":blur-factor=127", 
                    ":ipv4-timeout=3000", 
                    ":no-video-title-show", 
                    ":loop", 
                    ":sout-all",
                    ":sout-keep"
            };
            */
			mediaPlayer.playMedia(this.content.getLocalPath());
			
			/*
			 *  if pause video pause time is set to zero, it will run untill it finishes.
			 */
			
			if(PlayerUtilities.getVideoPasueTime() == 0)
			{
				synchronized (this.playLock) {
					try {
						this.playLock.wait();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
						LoggingUtils.log(Level.SEVERE, "unable to use vlc " + classMethod,e);
					}
				}
			}
			
		} catch(Exception e) {
			e.printStackTrace();
			LoggingUtils.log(Level.SEVERE, "unable to use vlc video library.: " + classMethod,e);
			supported = false;
			synchronized (this.playLock) {
				this.playLock.notifyAll();
			}
			
			final String exceptionmessage = EmailSending.FormatException(e);
			Thread emailingThread = new Thread(new Runnable() {
				@Override
				public void run() {

					String EmailBody = EmailSending.ProcessEmailBody(content.getLocalPath()+" Video has formating problem or VLC library problem", 
							"VLC error:Notification, Video not playing", exceptionmessage);

					util.EmailSending.getInstance().send(Settings.TO_USER, "VLC error:Notification" +
							"BoxID="+Preference.getInstance().getBoxID(), EmailBody);
				}
			});
			emailingThread.setName("Emailing");
			emailingThread.start();
			
			System.err.println("unable to use vlc video library.");
		} catch(Error err) {
			err.printStackTrace();
			LoggingUtils.log(Level.SEVERE, "unable to use vlc video library.: " + classMethod,err);
			supported = false;
			synchronized (this.playLock) {
				this.playLock.notifyAll();
			}
			System.err.println("unable to use vlc video library.");
			
			final String exceptionmessage = EmailSending.FormatException(err);
			Thread emailingThread = new Thread(new Runnable() {
				@Override
				public void run() {

					String EmailBody = EmailSending.ProcessEmailBody(content.getLocalPath()+" Video has formating problem or VLC library problem", 
							"VLC error:Notification, Video not playing", exceptionmessage);

					util.EmailSending.getInstance().send(Settings.TO_USER, "VLC error:Notification" +
							"BoxID="+Preference.getInstance().getBoxID(), EmailBody);
				}
			});
			emailingThread.setName("Emailing");
			emailingThread.start();
		}
	}

	// public static void main(String[] args) throws Exception {
	// if (args.length != 1) {
	// System.out.println("Specify an MRL to play");
	// System.exit(1);
	// }
	//
	// final EmbeddedMediaPlayerComponent mediaPlayerComponent = new
	// EmbeddedMediaPlayerComponent();
	//
	// JFrame f = new JFrame("Test Player");
	// f.setSize(800, 600);
	//
	// f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	// f.addWindowListener(new WindowAdapter() {
	// @Override
	// public void windowClosed(WindowEvent e) {
	// mediaPlayerComponent.release();
	// }
	// });
	// f.setContentPane(mediaPlayerComponent);
	// f.setVisible(true);
	//
	// mediaPlayerComponent.getMediaPlayer().playMedia(args[0]);
	//
	// Thread.currentThread().join();
	// }

	public void cleanup() {
		if (this.mediaPlayerComponent != null) {
			this.mediaPlayerComponent.release();
		}
	}

	@Override
	public void backward(MediaPlayer arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void buffering(MediaPlayer arg0) {
		// TODO Auto-generated method stub
	}

	@Override
	public void endOfSubItems(MediaPlayer arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void error(MediaPlayer arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void finished(MediaPlayer arg0) {
		synchronized(this.playLock) {
			this.playLock.notifyAll();
		}
		//this.cleanup();

	}

	@Override
	public void forward(MediaPlayer arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void lengthChanged(MediaPlayer arg0, long arg1) {
	}

	@Override
	public void mediaChanged(MediaPlayer arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void mediaDurationChanged(MediaPlayer arg0, long arg1) {
		// TODO Auto-generated method stub

	}

	@Override
	public void mediaFreed(MediaPlayer arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void mediaMetaChanged(MediaPlayer arg0, int arg1) {
		// TODO Auto-generated method stub

	}

	@Override
	public void mediaParsedChanged(MediaPlayer arg0, int arg1) {
		// TODO Auto-generated method stub

	}

	@Override
	public void mediaStateChanged(MediaPlayer arg0, int arg1) {
		// TODO Auto-generated method stub

	}

	@Override
	public void mediaSubItemAdded(MediaPlayer arg0, libvlc_media_t arg1) {
		// TODO Auto-generated method stub

	}

	@Override
	public void newMedia(MediaPlayer arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void opening(MediaPlayer arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void pausableChanged(MediaPlayer arg0, int arg1) {
		// TODO Auto-generated method stub

	}

	@Override
	public void paused(MediaPlayer arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void playing(MediaPlayer arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void positionChanged(MediaPlayer arg0, float arg1) {
		// TODO Auto-generated method stub

	}

	@Override
	public void seekableChanged(MediaPlayer arg0, int arg1) {
		// TODO Auto-generated method stub

	}

	@Override
	public void snapshotTaken(MediaPlayer arg0, String arg1) {
		// TODO Auto-generated method stub

	}

	@Override
	public void stopped(MediaPlayer arg0) {
	}

	@Override
	public void subItemFinished(MediaPlayer arg0, int arg1) {
		// TODO Auto-generated method stub

	}

	@Override
	public void subItemPlayed(MediaPlayer arg0, int arg1) {
		// TODO Auto-generated method stub

	}

	@Override
	public void timeChanged(MediaPlayer arg0, long arg1) {
		// TODO Auto-generated method stub

	}

	@Override
	public void titleChanged(MediaPlayer arg0, int arg1) {
		// TODO Auto-generated method stub

	}
}
class MyEmbeddedMediaPlayerComponent extends EmbeddedMediaPlayerComponent {
    @Override
    protected MediaPlayerFactory onGetMediaPlayerFactory() {
      return super.onGetMediaPlayerFactory();
    }

    @Override
    protected String[] onGetMediaPlayerFactoryArgs() {
    	return new String[] {"--no-xlib", "--no-overlay","--no-video-title-show"};
    }

    @Override
    protected FullScreenStrategy onGetFullScreenStrategy() {
      return super.onGetFullScreenStrategy();
    }

    @Override
    protected Canvas onGetCanvas() {
      return super.onGetCanvas();
    }

    @Override
    protected void onBeforeRelease() {
      super.onBeforeRelease();
    }

    @Override
    protected void onAfterRelease() {
      super.onAfterRelease();
    }

    // Override whatever listener methods you're interested in...
    
    @Override
    public void videoOutputAvailable(MediaPlayer mediaPlayer, boolean videoOutput) {
      super.videoOutputAvailable(mediaPlayer, videoOutput);
    }

    @Override
    public void playing(MediaPlayer mediaPlayer) {
      super.playing(mediaPlayer);
    }

    @Override
    public void error(MediaPlayer mediaPlayer) {
      super.error(mediaPlayer);
    }
  }
